/******************************************************************************
*  COPYRIGHT MorningCore CO.,LTD
******************************************************************************/

#include "../head/ue_tx_pusch_scrambling_f.h"

//#define _CRT_SECURE_NO_DEPRECATE
/******************************************************************************
*  INCLUDE FILES
******************************************************************************/
/*----------- function definition-----------------------------------*/
/*****************************************************************************
* Function: PUSCHScrambling()
* Purpose:  This function performs pusch bit scrambing
*
* Relation:
Calls       : ....
Called by   : ....
* Params:
*   <Name>          <Type>      <In/Out>    <Description>
  P_DataIp[95040]   int8           In         input binary bit
  PUSCH_BitLen		int			   In		  input length
  P_DataOp[95040]   int8           Out        output binary bit

* Return:  void
* Note:    <no>
*******************************************************************************/
void PUSCHScrambling_f
(
    IN int8 P_DataIp[],// input binary bit
    IN int  PUSCH_BitLen,
    IN  int P_CiniForScram,
    OUT int8    P_DataOp[]// output binary bit
)
{
    /*variables definition*/
    uint32  x1, x2;
    int8    c;
    int8    val;
    //int8  *P_Temp;

    int32   i;  //for cycle

    /*Init*/

    /*Function body*/
    x1 = 1;
    x2 = P_CiniForScram;

    val = (char)((x1 & 1) ^ ((x1 >> 3) & 1));
    x1 = x1 | (val << 31);
    val = (char)((x2 & 1) ^ ((x2 >> 1) & 1) ^ ((x2 >> 2) & 1) ^ ((x2 >> 3) & 1));
    x2 = x2 | (val << 31);

    //update x1,x2 sequence and calc c init val:
    for (i = 0; i < Nc; i++)
    {
        x1 = x1_update_usp(x1);  //
        x2 = x2_update_usp(x2);  //
    }
    c = (char)(x1 ^ x2) & 1;

    //scram input codeword bit:
    for (i = 0; i < PUSCH_BitLen; i++)
    {
        P_DataOp[i] = P_DataIp[i] ^ c;

        x1 = x1_update_usp(x1);  //
        x2 = x2_update_usp(x2);  //
        c = (char)(x1 ^ x2) & 1;
        //printf("%d\n",(x1^x2));
    }
}

//x1(n+31) = ( x1(n+3) + x1(n) ) % 2
uint32 x1_update_usp(uint32 x1)      //
{
    uint32 val;

    x1 = x1 >> 1;
    val = (x1 & 1) ^ ((x1 >> 3) & 1);
    x1 = x1 | (val << 31);

    return x1;
}

//x2(n+31) = ( x2(n+3) + x2(n+2) + x2(n+1) + x2(n) ) % 2
uint32 x2_update_usp(uint32 x2)     //
{
    uint32 val;
    x2 = x2 >> 1;
    val = (x2 & 1) ^ ((x2 >> 1) & 1) ^ ((x2 >> 2) & 1) ^ ((x2 >> 3) & 1);
    x2 = x2 | (val << 31);

    return x2;
}
